package com.tydic.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tydic.common.core.exception.ServiceException;
import com.tydic.common.core.service.UserService;
import com.tydic.system.domain.SysUser;
import com.tydic.system.domain.SysUserRole;
import com.tydic.system.domain.bo.QuerySysUserBo;
import com.tydic.system.domain.bo.SysUserBo;
import com.tydic.system.domain.vo.SysUserVo;
import com.tydic.system.mapper.*;
import com.tydic.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户 业务层处理
 *
 * @author Lion Li
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl implements ISysUserService, UserService {

    private final SysUserMapper baseMapper;
    private final SysDeptMapper deptMapper;
    private final SysRoleMapper roleMapper;
    private final SysPostMapper postMapper;
    private final SysUserRoleMapper userRoleMapper;
    private final SysUserPostMapper userPostMapper;


    @Override
    public SysUserVo selectByLoginCode(String loginCode) {
        SysUser sysUser = selectUserByLoginCode(loginCode);
        if (sysUser == null) {
            return null;
        }
        return BeanUtil.toBean(sysUser, SysUserVo.class);
    }

    @Override
    public SysUser getUserByLoginCode(String loginCode) {
        return selectUserByLoginCode(loginCode);
    }

    private SysUser selectUserByLoginCode(String loginCode) {
        return baseMapper.selectOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getLoginCode, loginCode), false);
    }


    @Override
    public boolean existsByLoginCode(String loginCode) {
        return baseMapper.exists(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getLoginCode, loginCode));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean insertByBo(SysUserBo bo) {
        SysUser sysUser = BeanUtil.toBean(bo, SysUser.class);
        return baseMapper.insert(sysUser) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateByBo(SysUserBo bo) {
        SysUser sysUser = BeanUtil.toBean(bo, SysUser.class);
        return baseMapper.updateById(sysUser) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean changePassword(String loginCode, String password) {
        SysUser sysUser = selectUserByLoginCode(loginCode);
        if (sysUser == null) {
            throw new ServiceException("修改密码失败");
        }
        sysUser.setPassword(password);
        return baseMapper.updateById(sysUser) > 0;
    }

    @Override
    public Page<SysUserVo> selectPageUserList(QuerySysUserBo bo) {
        return baseMapper.selectVoPage(bo.build(), buildLambdaQueryWrapper(BeanUtil.toBean(bo, SysUser.class)));
    }

    @Override
    public SysUserVo getById(String userCode) {
        SysUserVo sysUserVo = baseMapper.selectVoById(userCode);
        sysUserVo.setRoleCodes(userRoleMapper.selectRoleCodeByUserCode(userCode));
        return sysUserVo;
    }

    private LambdaQueryWrapper<SysUser> buildLambdaQueryWrapper(SysUser sysUser) {
        LambdaQueryWrapper<SysUser> lqw = Wrappers.lambdaQuery();
        lqw.like(CharSequenceUtil.isNotBlank(sysUser.getLoginCode()), SysUser::getLoginCode, sysUser.getLoginCode());
        lqw.like(CharSequenceUtil.isNotBlank(sysUser.getUserName()), SysUser::getUserName, sysUser.getUserName());
        lqw.like(CharSequenceUtil.isNotBlank(sysUser.getEmail()), SysUser::getEmail, sysUser.getEmail());
        lqw.like(CharSequenceUtil.isNotBlank(sysUser.getPhone()), SysUser::getPhone, sysUser.getPhone());
        lqw.like(CharSequenceUtil.isNotBlank(sysUser.getMobile()), SysUser::getMobile, sysUser.getMobile());
        lqw.eq(CharSequenceUtil.isNotBlank(sysUser.getStatus()), SysUser::getStatus, sysUser.getStatus());
        lqw.orderByDesc(SysUser::getUpdateDate);
        return lqw;
    }

    @Override
    public List<SysUser> getUsersByUserTypes(String... userTypes) {
        return baseMapper.selectList(Wrappers.lambdaQuery(SysUser.class).in(SysUser::getUserType, userTypes));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateUserType(String userCode, String userType) {
        SysUser sysUser = baseMapper.selectById(userCode);
        if (sysUser == null) {
            return;
        }
        sysUser.setUserType(userType);
        baseMapper.updateById(sysUser);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveUser(SysUser user, List<String> roleCodes) {
        baseMapper.insertOrUpdate(user);
        userRoleMapper.delete(Wrappers.lambdaQuery(SysUserRole.class).eq(SysUserRole::getUserCode, user.getUserCode()));
        if (CollUtil.isEmpty(roleCodes)) {
            return;
        }
        for (String roleCode : roleCodes) {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserCode(user.getUserCode());
            userRole.setRoleCode(roleCode);
            userRoleMapper.insert(userRole);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteByUserCode(String userCode) {
        userRoleMapper.delete(Wrappers.lambdaUpdate(SysUserRole.class).eq(SysUserRole::getUserCode, userCode));
        return baseMapper.deleteById(userCode) > 0;
    }
}
